package postgres

import (
	"context"
	"gorm.io/gorm"
	"manager/model"
	"manager/model/entity"
)

var ShareEbike = &shareEbike{}

type shareEbike struct{}

// Create 创建
func (a *shareEbike) Create(ctx context.Context, m *entity.ShareEbike) (int64, error) {
	err := GetDB(ctx).Create(m).Error
	return m.Id, err
}

// Find 查找详情
func (a *shareEbike) Find(ctx context.Context, id int64) (*entity.ShareEbike, error) {
	e := &entity.ShareEbike{}
	err := GetDB(ctx).Model(&entity.ShareEbike{}).First(&e, id).Error
	return e, err
}

// Update 更新
func (a *shareEbike) Update(ctx context.Context, id int64, dict map[string]interface{}) error {
	return GetDB(ctx).Model(&entity.ShareEbike{}).Where("id = ?", id).Updates(dict).Error
}

// Delete 删除
func (a *shareEbike) Delete(ctx context.Context, id int64) error {
	return GetDB(ctx).Delete(&entity.ShareEbike{}, id).Error
}

// List 列表查询
func (a *shareEbike) List(ctx context.Context, in *model.ShareEbikeListRequest) (int, []*entity.ShareEbike, error) {
	var (
		q           = GetDB(ctx).Model(&entity.ShareEbike{})
		err         error
		total       int64
		shareEbikes []*entity.ShareEbike
	)

	if in.UserId != nil {
		q = q.Where("user_id = ?", *in.UserId)
	}

	if len(in.BikeIds) > 0 {
		q = q.Where("ebike_id in (?)", in.BikeIds)
	}

	if in.EbikeId != nil {
		q = q.Where("ebike_id = ?", *in.EbikeId)
	}

	if in.ShareUserId != nil {
		q = q.Where("share_user_id = ?", *in.ShareUserId)
	}

	if in.Phone != nil {
		q = q.Where("phone = ?", *in.Phone)
	}

	if in.Name != nil {
		q = q.Where("name like ?", "%"+*in.Name+"%")
	}

	if in.ShareTime != nil {
		q = q.Where("share_time = ?", *in.ShareTime)
	}

	if in.Status != nil {
		q = q.Where("status = ?", *in.Status)
	}

	if in.CreatedAt != nil {
		q = q.Where("updated_at = ?", *in.CreatedAt)
	}

	if len(in.FilterStatus) > 0 {
		q = q.Where("status not in (?)", in.FilterStatus)
	}

	if err = q.Count(&total).Error; err != nil {
		return 0, nil, err
	}
	if err = q.Order("created_at desc").Limit(in.Size).Offset((in.Index - 1) * in.Size).Find(&shareEbikes).Error; err != nil {
		return 0, nil, err
	}
	return int(total), shareEbikes, nil
}

// ShareAll 用户根据车辆分享详情
func (a *shareEbike) ShareAll(ctx context.Context, userId int64) ([]*model.EbikeList, error) {

	var (
		err error
		out = make([]*model.EbikeList, 0)
	)

	// 分享列表
	var shareList []*entity.ShareEbike
	sql := "select ebike_id, user_id, max(created_at) as created_at from share_ebikes where user_id = ? group by ebike_id, user_id;"
	err = GetDB(ctx).Raw(sql, userId).Scan(&shareList).Error
	shareMap := make(map[int64]*entity.ShareEbike)
	for i := 0; i < len(shareList); i++ {
		shareMap[shareList[i].EbikeId] = shareList[i]
	}

	sql = "select  ue.created_at,e.name,ue.photo,ue.ebike_id id from user_ebikes ue ,ebikes e " +
		"where e.id = ue.ebike_id and ue.user_id = ? and ue.is_manager = ? and ue.ebike_id in " +
		"(select s.ebike_id from share_ebikes s where s.user_id = ? group by s.ebike_id)"
	// 查询用户的车辆 并且在 分享车辆表里面有几个
	err = db.Raw(sql, userId, model.IsManagerYes, userId).Scan(&out).Error

	for i := 0; i < len(out); i++ {
		if v, ok := shareMap[out[i].ID]; ok {
			out[i].CreatedAt = v.CreatedAt
		}
	}
	return out, err
}

// ExecTransaction db事务执行
func (a *shareEbike) ExecTransaction(ctx context.Context, callback func(ctx context.Context) error) error {
	return GetDB(ctx).Transaction(func(tx *gorm.DB) error {
		ctx = context.WithValue(ctx, DBCONTEXTKEY, tx)
		return callback(ctx)
	})
}
